<template>
  <span ref="switch" @click="change" :class="switchClass" :style="switchStyle">
    <input type="hidden" :value="value" :name="name" />
    <!-- switch内部切换小球 -->
    <span ref="circle" :class="circleClass" :style="circleStyle"></span>
    <div v-show="value" :class="[size=='small'?'vbestui-open-small':'',`${prefixCls+'-open'}`]">
      <slot name="open">
        <i></i>
      </slot>
    </div>
    <div v-show="!value" :class="[size=='small'?'vbestui-close-small':'',`${prefixCls+'-close'}`]">
      <slot name="close">
        <i></i>
      </slot>
    </div>
  </span>
</template>
<script>
import { oneOf } from "utils/index.js";
const prefixCls = "vbestui-switch";
export default {
  name: "BSwitch",
  data() {
    return {
      prefixCls: prefixCls,
      offsetX: 0, //switch为true时circle偏移量
      circleHeight: 0, //自定义高度时circle高度
    };
  },
  props: {
    value: {
      type: Boolean,
      default: false,
    },
    width: {
      type: Number,
      default: 0,
    },
    height: {
      type: Number,
      default: 0,
    },
    size: {
      validator(value) {
        return oneOf(value, ["large", "default", "small"]);
      },
      default: "default",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    trueColor: {
      type: String,
      default: "",
    },
    falseColor: {
      type: String,
      default: "",
    },
    name: {
      type: String,
      default: "",
    },
  },
  computed: {
    switchClass() {
      return [
        `${this.prefixCls}`,
        `${this.prefixCls + "-" + this.size}`,
        this.value ? "vbestui-switch-active" : "",
        this.disabled ? `${this.prefixCls + "-disabled"}` : "",
      ];
    },
    switchStyle() {
      return {
        backgroundColor: this.value ? this.trueColor : this.falseColor,
        width: this.width !== 0 ? `${this.width}px` : "",
        height: this.height !== 0 ? `${this.height}px` : "",
      };
    },
    circleClass() {
      return [
        `${this.prefixCls + "-circle"}`,
        `${this.prefixCls + "-circle-" + this.size}`,
        // 不设置宽度、高度时启用css切换动画，设置宽度时不用css动画
        !this.isSetSwitch
          ? ""
          : this.value
          ? `${this.prefixCls}-circle-active-${this.size}`
          : `${this.prefixCls}-circle-unactive-${this.size}`,
      ];
    },
    circleStyle() {
      return {
        // switch内部开关小球左临界值为2，右侧临界值switch宽度-circle宽度-2
        height: this.height !== 0 ? `${this.circleHeight}px` : "",
        width: this.height !== 0 ? `${this.circleHeight}px` : "",
        transform: !this.isSetSwitch
          ? this.value
            ? `translateX(${this.offsetX}px)`
            : `translateX(${2}px)`
          : "",
        transition: !this.isSetSwitch ? `transform .4s` : "",
      };
    },
    /**是否设置了宽高
     * true既没设置宽也没设置高
     */
    isSetSwitch() {
      return this.width === 0 && this.height === 0;
    },
  },
  methods: {
    change() {
      if (this.disabled) return;
      this.$emit("input", !this.value);
      this.$emit("toggle");
    },
    initSwitch() {
      this.$nextTick(() => {
        /**只自定义宽度 */
        if (this.width !== 0 && this.height === 0) {
          this.offsetX = this.width - this.$refs.circle.offsetWidth - 2;
        }
        /**只自定义高度 */
        if (this.width === 0 && this.height !== 0) {
          this.circleHeight = this.height - 4;
          this.offsetX = this.$refs.switch.offsetWidth - this.circleHeight - 2;
        }
        /**即设置了宽度又设置高度 */
        if (this.width !== 0 && this.height !== 0) {
          this.circleHeight = this.height - 4;
          this.offsetX = this.width - this.circleHeight - 2;
        }
      });
    },
  },
  created() {
    this.initSwitch();
  },
  watch: {
    height() {
      this.initSwitch();
    },
    width() {
      this.initSwitch();
    },
  },
};
</script>